package com.pwr.sip;

import java.awt.Choice;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;

import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JFormattedTextField.AbstractFormatter;
import javax.swing.JFormattedTextField.AbstractFormatterFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.InternationalFormatter;

import com.pwr.sip.Strings.Locations;
import com.pwr.sip.Strings.NoiseMethods;

public class NoiseWindow extends JDialog implements ActionListener, ItemListener {
	private static final long serialVersionUID = 1L;
	JDialog jDialog;
	Choice locationChoice;
	JFormattedTextField percentageValue;
	JFormattedTextField polesValue;
	JFormattedTextField alphaValue;
	JRadioButton[] radioButtons = new JRadioButton[3];
	String[] radioNames = { "Gauss", "Hover", "Flip" };

	JPanel radioButtonPanel = new JPanel();
	JButton okButton = new JButton("OK");
	JButton cancelButton = new JButton("Cancel");
	JButton addPercentage;
	JButton subtractPercentage;
	JButton addPoles;
	JButton subtractPoles;
	JButton addAlpha;
	JButton subtractAlpha;
	JLabel alphaText;
	JLabel polesText;
	JLabel percentageText;
	JLabel locationText;

	JPanel actionButtons = new JPanel();

	JPanel noiseVariables = new JPanel();
	JPanel totalGUI = new JPanel(new GridLayout(3, 1));

	public Strings.NoiseMethods method = NoiseMethods.GAUSS;
	public int poles = 5;
	public double alpha = 0.0;

	public double percentage = 25.0;
	public Strings.Locations location = Strings.Locations.LEFT;

	private int fontSize = 13;

	public NoiseWindow(JFrame parent, String title, String message) {
		super(parent, title, true);
		Dimension parentSize = parent.getSize();
		Point p = parent.getLocation();
		setLocation(p.x + parentSize.width / 4, p.y + parentSize.height / 4);
		CreateAndShowGUI(parent, title);
	}

	private void CreateAndShowGUI(JFrame parent, String title) {
		jDialog = new JDialog(parent, title); // Creates dialog
		jDialog.setModal(true); // Means it will wait
		jDialog.add(createPanel()); // Add your panel
		jDialog.pack(); // Set size (probably want this relating to your panel
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		jDialog.setLocation(dim.width / 2 - jDialog.getWidth() / 2, dim.height / 2 - jDialog.getHeight() / 2);
		jDialog.setVisible(true);
		jDialog.setResizable(false);
		jDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

	}

	private JPanel createPanel() {
		prepareRadioButtons(this);
		prepareActionButtons(this);
		setNoiseVariables("Gauss");
		totalGUI.add(radioButtonPanel);
		totalGUI.add(noiseVariables);
		totalGUI.add(actionButtons);
		totalGUI.setName("DUPA");
		return totalGUI;
	}

	private void exit() {
		jDialog.dispose();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();
		String buttonName = ((AbstractButton) source).getActionCommand();

		if (buttonName == "Gauss") {
			method = Strings.NoiseMethods.GAUSS;
			setNoiseVariables("Gauss");
			((AbstractButton) radioButtonPanel.getComponent(1)).setSelected(false);
			((AbstractButton) radioButtonPanel.getComponent(2)).setSelected(false);
			changePanelContent(1, noiseVariables);
		}
		if (buttonName == "Hover") {
			method = Strings.NoiseMethods.HOVER;
			setNoiseVariables("Hover");
			((AbstractButton) radioButtonPanel.getComponent(0)).setSelected(false);
			((AbstractButton) radioButtonPanel.getComponent(2)).setSelected(false);
			changePanelContent(1, noiseVariables);
		} else if (buttonName == "Flip") {
			method = Strings.NoiseMethods.FLIP;
			setNoiseVariables("Flip");
			((AbstractButton) radioButtonPanel.getComponent(0)).setSelected(false);
			((AbstractButton) radioButtonPanel.getComponent(1)).setSelected(false);
			changePanelContent(1, noiseVariables);
		} else if (source == okButton) {
			if (alphaValue != null)
				alpha = Double.parseDouble(alphaValue.getText());
			if (percentageValue != null)
				percentage = Double.parseDouble(percentageValue.getText());
			if (polesValue != null)
				poles = Integer.parseInt(polesValue.getText());
			exit();
		} else if (source == cancelButton) {
			method = Strings.NoiseMethods.NONE;
			exit();
		} else if (source == addPoles) {
			poles++;
			polesValue.setText(poles + "");
		} else if (source == addPoles) {
			poles++;
			polesValue.setText(poles + "");
		} else if (source == subtractPoles) {
			if (poles > 1)
				poles--;
			else
				poles = 1;
			polesValue.setText(poles + "");
		} else if (source == addAlpha) {
			if (alpha <= 1.9)
				alpha = alpha + 0.10;
			else
				alpha = 2.0;
			alphaValue.setText(alpha + "");
		} else if (source == subtractAlpha) {
			if (alpha > 0.0)
				alpha = alpha - 0.10;
			else
				alpha = 0.0;
			alphaValue.setText(alpha + "");
		} else if (source == addPercentage) {
			if (percentage < 100)
				percentage++;
			else
				percentage = 100.00;
			percentageValue.setText(percentage + "");
		} else if (source == subtractPercentage) {
			if (percentage >= 2.0)
				percentage--;
			else
				percentage = 1.0;
			percentageValue.setText(percentage + "");
		} else if (source == percentageValue) {

		}

	}

	public void prepareRadioButtons(ActionListener al) {
		for (int i = 0; i < radioButtons.length; i++) {
			radioButtons[i] = new JRadioButton();
			if (i == 0)
				radioButtons[i].setSelected(true);
			radioButtons[i].setText(radioNames[i]);
			radioButtons[i].addActionListener(al);
			radioButtonPanel.add(radioButtons[i]);
		}
	}

	public void prepareActionButtons(ActionListener al) {
		okButton.setText("OK");
		okButton.addActionListener(al);
		cancelButton.setText("Cancel");
		cancelButton.addActionListener(al);
		actionButtons.add(okButton);
		actionButtons.add(cancelButton);
	}

	private void setNoiseVariables(String noiseMethod) {
		if (noiseMethod == radioNames[1]) // Hover
		{
			prepareHoverFlip();
		} else if (noiseMethod == radioNames[2]) // Flip
		{
			prepareHoverFlip();
		} else // Gauss
		{
			prepareGauss();
		}
	}

	public void changePanelContent(int componentPosition, JPanel jPanel) {
		totalGUI.remove(componentPosition);
		totalGUI.add(jPanel, componentPosition);
		refreshGUI();
	}

	public void refreshGUI() {
		jDialog.pack();
		jDialog.invalidate();
	}

	private void prepareLocationElements() {
		for (Locations location : Locations.values()) {
			locationChoice.add(location + "");
		}
		locationChoice.addItemListener(this);
	}

	@Override
	public void itemStateChanged(ItemEvent e) {
		location = Strings.Locations.stringToLocation(locationChoice.getSelectedItem());
	}

	private void prepareGauss() {
		noiseVariables = new JPanel(new GridLayout(2, 2));

		polesText = new JLabel(" Poles number:");
		polesText.setToolTipText("Value for poles; cannot be less than 1 (default is: 5)");

		alphaText = new JLabel(" Alpha value:");
		alphaText.setToolTipText("<html>Value for alpha: between 0.0 - 2.0 (default is: 0.0)<br>-> 0.0 - Gauss noise <br>" + "-> 1.0 - Pink noise <br>-> 2.0 - Brown noise</html>");
		polesValue = new JFormattedTextField(new Integer(poles));
		polesValue.setEditable(true);

		polesValue.setFormatterFactory(new AbstractFormatterFactory() {

			@Override
			public AbstractFormatter getFormatter(JFormattedTextField tf) {
				NumberFormat format = DecimalFormat.getNumberInstance(Locale.US);
				format.setGroupingUsed(false);
				format.setMinimumFractionDigits(0);
				format.setMaximumFractionDigits(0);
				InternationalFormatter formatter = new InternationalFormatter(format);
				formatter.setAllowsInvalid(false);
				formatter.setMinimum(1);
				formatter.setMaximum(10000);
				return formatter;
			}
		});

		// Listen for changes in the text
		polesValue.getDocument().addDocumentListener(new DocumentListener() {
			@Override
			public void changedUpdate(DocumentEvent arg0) {
				// TODO Auto-generated method stub
				// poles = Integer.parseInt(polesValue.getText());
			}

			@Override
			public void insertUpdate(DocumentEvent arg0) {
				// TODO Auto-generated method stub
				poles = Integer.parseInt(polesValue.getText());

			}

			@Override
			public void removeUpdate(DocumentEvent arg0) {
				// TODO Auto-generated method stub

			}
		});

		alphaValue = new JFormattedTextField(new Double(alpha));
		alphaValue.setEditable(true);

		alphaValue.setFormatterFactory(new AbstractFormatterFactory() {

			@Override
			public AbstractFormatter getFormatter(JFormattedTextField tf) {
				NumberFormat format = DecimalFormat.getNumberInstance(Locale.US);
				format.setMinimumFractionDigits(2);
				format.setMaximumFractionDigits(2);
				InternationalFormatter formatter = new InternationalFormatter(format);
				formatter.setAllowsInvalid(false);
				formatter.setMinimum(0.00);
				formatter.setMaximum(2.00);
				return formatter;
			}
		});

		// Listen for changes in the text
		alphaValue.getDocument().addDocumentListener(new DocumentListener() {
			@Override
			public void changedUpdate(DocumentEvent arg0) {
				// TODO Auto-generated method stub
				// alpha = Double.parseDouble(alphaValue.getText());
			}

			@Override
			public void insertUpdate(DocumentEvent arg0) {
				// TODO Auto-generated method stub
				alpha = Double.parseDouble(alphaValue.getText());
			}

			@Override
			public void removeUpdate(DocumentEvent arg0) {
				// TODO Auto-generated method stub
			}
		});

		JPanel advancedSet = new JPanel(new GridLayout(1, 2));
		JPanel plusMinusButtons = new JPanel(new GridLayout(1, 2));
		addPoles = new JButton("+");
		subtractPoles = new JButton("-");
		addPoles.addActionListener(this);
		subtractPoles.addActionListener(this);
		plusMinusButtons.add(addPoles);
		plusMinusButtons.add(subtractPoles);
		advancedSet.add(polesValue);
		advancedSet.add(plusMinusButtons);

		noiseVariables.add(polesText);
		noiseVariables.add(advancedSet);

		advancedSet = new JPanel(new GridLayout(1, 2));
		plusMinusButtons = new JPanel(new GridLayout(1, 2));
		addAlpha = new JButton("+");
		subtractAlpha = new JButton("-");
		addAlpha.addActionListener(this);
		subtractAlpha.addActionListener(this);
		plusMinusButtons.add(addAlpha);
		plusMinusButtons.add(subtractAlpha);
		advancedSet.add(alphaValue);
		advancedSet.add(plusMinusButtons);
		noiseVariables.add(advancedSet);

		noiseVariables.add(alphaText);
		noiseVariables.add(advancedSet);
	}

	private void prepareHoverFlip() {
		noiseVariables = new JPanel(new GridLayout(2, 2));
		JLabel percentage = new JLabel(" Percentage value:");
		percentage.setToolTipText("Percentage cover value; cannot be less than 0.0 (default is: 12.5)");
		JLabel location = new JLabel(" Location:");
		location.setToolTipText("<html>Flip location: (default is: LEFT)<br>-> LEFT - left side of picture <br>"
				+ "-> VERTICALCENTER - vertical center of picture <br>-> RIGHT - right side of picture" + "<br>-> BOTTOM - bottom of picture <br>-> TOP - top of picture"
				+ "<br>-> HORIZONTALCENTER - horizontal center of picture</html>");
		percentageValue = new JFormattedTextField((this.percentage));
		percentageValue.setEditable(true);

		percentageValue.setFormatterFactory(new AbstractFormatterFactory() {

			@Override
			public AbstractFormatter getFormatter(JFormattedTextField tf) {
				NumberFormat format = DecimalFormat.getNumberInstance(Locale.US);
				format.setMinimumFractionDigits(2);
				format.setMaximumFractionDigits(2);
				format.setRoundingMode(RoundingMode.HALF_UP);
				InternationalFormatter formatter = new InternationalFormatter(format);
				formatter.setAllowsInvalid(false);
				formatter.setMinimum(1.00);
				formatter.setMaximum(100.00);
				return formatter;
			}
		});

		// Listen for changes in the text
		percentageValue.getDocument().addDocumentListener(new DocumentListener() {
			@Override
			public void changedUpdate(DocumentEvent arg0) {
				// TODO Auto-generated method stub
				// NoiseWindow.this.percentage =
				// Double.parseDouble(percentageValue.getText());
			}

			@Override
			public void insertUpdate(DocumentEvent arg0) {
				// TODO Auto-generated method stub
				NoiseWindow.this.percentage = Double.parseDouble(percentageValue.getText());
			}

			@Override
			public void removeUpdate(DocumentEvent arg0) {
				// TODO Auto-generated method stub
			}
		});

		locationChoice = new Choice();
		prepareLocationElements();

		noiseVariables.add(percentage);

		JPanel percentageSet = new JPanel(new GridLayout(1, 2));
		JPanel plusMinusButtons = new JPanel(new GridLayout(1, 2));
		addPercentage = new JButton("+");
		addPercentage.addActionListener(this);
		subtractPercentage = new JButton("-");
		subtractPercentage.addActionListener(this);
		plusMinusButtons.add(addPercentage);
		plusMinusButtons.add(subtractPercentage);
		percentageSet.add(percentageValue);
		percentageSet.add(plusMinusButtons);
		noiseVariables.add(percentageSet);

		noiseVariables.add(location);
		noiseVariables.add(locationChoice);
	}
}
